/*
 * $Id$
 */

package corejs.rt;

import java.math.BigDecimal;

/**
 *
 * @author pengyu
 */
public class Int extends Number {

   /**
    * 
    */
   private static class ReadOnlyInt extends Int {
      
      ReadOnlyInt(final int i) {super(i);}

      @Override
      public Int setValue(final int i) {
         return this;   
      }
   }
   
   public static final Int ZERO      = new ReadOnlyInt(0);
   public static final Int ONE       = new ReadOnlyInt(1); 
   public static final Int MINUS_ONE = new ReadOnlyInt(-1);
   
   private int _val;
   private BigDecimal _d; 

   public Int(final int val) {      
      _val = val;
      _d = new BigDecimal(_val);
   }
   
   public Int() { this(0); }
   
   /**
    *
    * @param i
    * @return
    */
   public static Int valueOf(final int i) {
      return -1 == i ? MINUS_ONE
         :    0 == i ? ZERO
         :    1 == i ? ONE
         :             new Int(i);
   }

   @Override public long longValue() {return _val;}

   @Override public int intValue() {return _val;}
   
   public Int setValue(final int val) {
      _val = val;
      _d = new BigDecimal(_val);
      return this;
   }

   @Override
   public String toString() {return String.valueOf(_val);}

   @Override
   public Bool toBool() {return 0 == _val ? Bool.FALSE : Bool.TRUE;}

   @Override
   public Str toStr() {return new Str(_val);}
   
   // ----------------------------------
   // equals
   @Override
   public boolean equals(final Number y) {return y.equals(_val);}

   @Override
   public boolean equals(final int i) {return _val == i;}
   
   @Override
   public boolean equals(final long i) {return _val == i;}
   
   @Override
   public boolean equals(final BigDecimal d) {return d.compareTo(_d) == 0;}

    // ----------------------------------
   // add
   @Override
   public Number add(final Number n) {return n.add(_val);}

   @Override
   protected Number add(final int i) {return valueOf(_val + i);}

   @Override
   protected Number add(final long i) {return Long.valueOf(_val + i);}

   @Override
   protected Number add(final BigDecimal d) {
      return new Decimal(d.add(_d));
   }

   // ----------------------------------
   // multiply
   @Override
   public Number multiply(final Number n) {return n.multiply(_val);}

   @Override
   protected Number multiply(final int i) {return valueOf(_val * i);}

   @Override
   protected Number multiply(final long l) {return Long.valueOf(_val * l);}

   @Override
   protected Number multiply(final BigDecimal d) {
      return new Decimal(d.multiply(_d));
   }

   // ----------------------------------
   // subtract
   @Override
   public Number subtract(final Number n) { return n.subtract(_val); }

   @Override
   protected Number subtract(final int i) {return valueOf(i - _val);}

   @Override
   protected Number subtract(final long l) {return Long.valueOf(l - _val);}

   @Override
   protected Number subtract(final BigDecimal d) {
      return new Decimal(d.subtract(_d));
   }

   // ----------------------------------
   // compareTo 
   @Override
   public Number compareTo(final Number other) {return other.compareTo(_val);}

   @Override
   Number compareTo(final long l) {return compareTo((int)l);}

   @Override
   Number compareTo(final BigDecimal d) {
      final int i = d.compareTo(_d);
      return 0 == i ? ZERO
           :  i < 0 ? MINUS_ONE
           :          ONE;
   }

   @Override
   Number compareTo(final int i) {
      return _val == i ? ZERO
            : _val > i ? MINUS_ONE
            :            ONE;
   }
   
   @Override public Int neg() {return valueOf(-_val);}

}
